# coding=utf-8
"""

4. 使用米粒图像，分割得到各米粒，首先计算各区域(米粒)的面积、长度等信息，进一步计算面积、长度的均值及方差，分析落在3sigma范围内米粒的数量。
结果分析：（摘要）（完整数据在最下方）
（米粒面积不足 10 的视为噪声忽略不计）
米粒总数量:  93
------------------------------
总面积: 14130.5
平均面积: 151.94086021505376
面积方差： 3877.7411261417515
面积标准差: 62.27151135263823
面积 3-Sigma 的取值范围: -34.874 - 338.76
米粒面积在 3-Sigma 内的数量为: 91
米粒面积在 3-Sigma 内的比例为: 97.849%
------------------------------
平均长度: 19.913978494623656
长度方差: 50.573245461903106
长度标准差: 7.111486867168012
平均宽度: 17.548387096774192
宽度方差: 57.15088449531738
宽度标准差: 7.559820400996136

"""

import cv2 as cv
import copy
import numpy as np

RiceFilename = r'rice.png'
AreaThreshold = 10
image = cv.imread(RiceFilename)
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
_, bw = cv.threshold(gray, 0, 255, cv.THRESH_OTSU)
element = cv.getStructuringElement(cv.MORPH_CROSS, (3, 3))  # 用于形态学的的算子构建，第一个参数便是内核的形状（矩形，交叉形，椭圆形）
bw = cv.morphologyEx(bw, cv.MORPH_OPEN, element)  # 数学形态学去噪

#cv.imshow("Source", image)
#cv.imshow("Gray", bw)

seg = copy.deepcopy(bw)
bin, cnts, hier = cv.findContours(seg, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
count = 0
areas = []
widths = []
heights = []

for i in range(len(cnts), 0, -1):
    cnt = cnts[i-1]
    area = cv.contourArea(cnt)
    if area < AreaThreshold:
        continue
    count = count + 1
    areas.append(area)


    #minAreaRect = cv.minAreaRect(cnt)
    #x, y, w, h = cv.boxPoints(minAreaRect)

    x, y, w, h = cv.boundingRect(cnt)
    widths.append(w)
    heights.append(h)
    print("Grain ", i, " : Area = {}, Width = {}, Height = {}".format(area, w, h))
    cv.rectangle(image, (x,y), (x+w, y+h), (0, 0, 0xff), 1)
    cv.putText(image, str(count), (x, y), cv.FONT_HERSHEY_PLAIN, 0.5, (0, 0xff, 0))


cv.imshow("Source", image)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/4_1.JPG
cv.imshow("Gray", bw)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/4_2.JPG

print("Number of grains(Area Threshold - {}): {}".format(AreaThreshold, count) )
print("Sum of grain areas: ", np.sum(areas))

meanOfAreas = np.mean(areas)
print("Average grain area：", meanOfAreas)
print("Average grain width：", np.mean(widths))
print("Average grain height：", np.mean(heights))

print("Variance of grain areas：", np.var(areas))
print("Variance of grain widths：", np.var(widths))
print("Variance of grain heights：", np.var(heights))

SD = np.std(areas)
print("SD of grain areas：", SD)
print("SD of grain widths：", np.std(widths))
print("SD of grain heights：", np.std(heights))

numbOfAreasWithin3Simgas = 0
for area in areas:
    if abs(area - meanOfAreas) <= 3*SD :
        numbOfAreasWithin3Simgas += 1

print("3-Sigma inverval: {:.5} - {:.5} ".format(meanOfAreas - 3*SD, meanOfAreas + 3*SD))
print("Number of grain areas wighin 3 sigmas：", numbOfAreasWithin3Simgas)
print("{:.5}% ".format(numbOfAreasWithin3Simgas/count*100))
cv.waitKey()
cv.destroyAllWindows()

"""

Grain  95  : Area = 47.0, Width = 10, Height = 9
Grain  94  : Area = 112.5, Width = 18, Height = 14
Grain  93  : Area = 163.0, Width = 11, Height = 25
Grain  91  : Area = 11.0, Width = 7, Height = 4
Grain  90  : Area = 103.0, Width = 13, Height = 18
Grain  89  : Area = 165.5, Width = 19, Height = 21
Grain  88  : Area = 35.0, Width = 10, Height = 7
Grain  87  : Area = 76.0, Width = 7, Height = 16
Grain  86  : Area = 99.0, Width = 20, Height = 10
Grain  85  : Area = 176.0, Width = 13, Height = 28
Grain  84  : Area = 123.0, Width = 14, Height = 21
Grain  83  : Area = 157.0, Width = 9, Height = 28
Grain  82  : Area = 169.5, Width = 16, Height = 23
Grain  81  : Area = 187.0, Width = 26, Height = 16
Grain  80  : Area = 167.0, Width = 11, Height = 27
Grain  79  : Area = 375.0, Width = 42, Height = 23
Grain  78  : Area = 117.5, Width = 13, Height = 22
Grain  77  : Area = 168.5, Width = 21, Height = 18
Grain  76  : Area = 141.5, Width = 18, Height = 18
Grain  75  : Area = 161.0, Width = 27, Height = 11
Grain  74  : Area = 202.0, Width = 29, Height = 12
Grain  73  : Area = 185.0, Width = 20, Height = 23
Grain  72  : Area = 178.5, Width = 28, Height = 15
Grain  71  : Area = 180.0, Width = 25, Height = 17
Grain  70  : Area = 133.0, Width = 19, Height = 17
Grain  69  : Area = 162.0, Width = 13, Height = 26
Grain  68  : Area = 139.5, Width = 15, Height = 21
Grain  67  : Area = 170.5, Width = 13, Height = 29
Grain  66  : Area = 200.0, Width = 21, Height = 26
Grain  65  : Area = 162.5, Width = 13, Height = 26
Grain  64  : Area = 106.0, Width = 13, Height = 17
Grain  63  : Area = 167.0, Width = 21, Height = 20
Grain  62  : Area = 180.0, Width = 10, Height = 29
Grain  61  : Area = 192.5, Width = 9, Height = 31
Grain  60  : Area = 181.0, Width = 24, Height = 21
Grain  59  : Area = 174.5, Width = 13, Height = 26
Grain  58  : Area = 359.5, Width = 38, Height = 27
Grain  57  : Area = 89.0, Width = 14, Height = 12
Grain  56  : Area = 47.0, Width = 4, Height = 23
Grain  55  : Area = 192.5, Width = 27, Height = 13
Grain  54  : Area = 190.5, Width = 23, Height = 23
Grain  53  : Area = 213.0, Width = 23, Height = 25
Grain  52  : Area = 215.5, Width = 18, Height = 28
Grain  51  : Area = 192.0, Width = 10, Height = 28
Grain  50  : Area = 158.5, Width = 25, Height = 17
Grain  49  : Area = 333.5, Width = 34, Height = 30
Grain  48  : Area = 146.0, Width = 13, Height = 27
Grain  47  : Area = 168.5, Width = 28, Height = 12
Grain  46  : Area = 156.5, Width = 10, Height = 29
Grain  45  : Area = 181.0, Width = 10, Height = 28
Grain  44  : Area = 201.0, Width = 28, Height = 16
Grain  43  : Area = 161.0, Width = 10, Height = 29
Grain  42  : Area = 170.5, Width = 20, Height = 20
Grain  41  : Area = 175.5, Width = 9, Height = 29
Grain  40  : Area = 194.0, Width = 19, Height = 27
Grain  39  : Area = 146.0, Width = 26, Height = 10
Grain  38  : Area = 199.0, Width = 9, Height = 31
Grain  37  : Area = 155.5, Width = 22, Height = 12
Grain  36  : Area = 190.5, Width = 30, Height = 12
Grain  35  : Area = 133.5, Width = 20, Height = 16
Grain  34  : Area = 157.5, Width = 9, Height = 27
Grain  33  : Area = 192.0, Width = 26, Height = 20
Grain  32  : Area = 175.0, Width = 22, Height = 24
Grain  31  : Area = 191.0, Width = 30, Height = 9
Grain  30  : Area = 128.0, Width = 17, Height = 22
Grain  29  : Area = 164.0, Width = 8, Height = 29
Grain  28  : Area = 94.5, Width = 13, Height = 16
Grain  27  : Area = 242.0, Width = 26, Height = 33
Grain  26  : Area = 170.0, Width = 22, Height = 23
Grain  25  : Area = 181.0, Width = 13, Height = 28
Grain  24  : Area = 154.0, Width = 14, Height = 25
Grain  23  : Area = 180.0, Width = 20, Height = 22
Grain  22  : Area = 172.5, Width = 15, Height = 27
Grain  21  : Area = 61.0, Width = 13, Height = 7
Grain  20  : Area = 160.5, Width = 27, Height = 10
Grain  19  : Area = 193.5, Width = 23, Height = 22
Grain  18  : Area = 160.0, Width = 12, Height = 28
Grain  17  : Area = 133.5, Width = 19, Height = 16
Grain  16  : Area = 134.5, Width = 26, Height = 14
Grain  15  : Area = 134.0, Width = 12, Height = 23
Grain  14  : Area = 176.0, Width = 19, Height = 22
Grain  13  : Area = 156.0, Width = 24, Height = 16
Grain  12  : Area = 154.0, Width = 23, Height = 11
Grain  11  : Area = 72.0, Width = 8, Height = 18
Grain  10  : Area = 130.5, Width = 17, Height = 23
Grain  8  : Area = 42.0, Width = 14, Height = 8
Grain  7  : Area = 45.5, Width = 16, Height = 5
Grain  6  : Area = 41.0, Width = 8, Height = 17
Grain  5  : Area = 77.5, Width = 12, Height = 19
Grain  4  : Area = 14.5, Width = 7, Height = 7
Grain  3  : Area = 84.0, Width = 16, Height = 14
Grain  2  : Area = 89.5, Width = 7, Height = 19
Grain  1  : Area = 31.0, Width = 13, Height = 9
Number of grains(Area Threshold - 10): 93
Sum of grain areas:  14130.5
Average grain area： 151.94086021505376
Average grain width： 17.548387096774192
Average grain height： 19.913978494623656
Variance of grain areas： 3877.7411261417515
Variance of grain widths： 57.15088449531738
Variance of grain heights： 50.573245461903106
SD of grain areas： 62.27151135263823
SD of grain widths： 7.559820400996136
SD of grain heights： 7.111486867168012
3-Sigma inverval: -34.874 - 338.76 
Number of grain areas wighin 3 sigmas： 91
97.849% 

"""



